import cv2 as cv
import numpy as np

# OpenCV图像变换包括仿射变换(affine transform)与透视变换(perspective transform)，他们在图像还原、图像局部变化处理方面有重要意义，
# 计算方法为坐标向量和变换矩阵的乘积。在应用层面，仿射变换是图像基于3个固定顶点的变换，而透视变换的顶点数为4个，且其中任意3点不能共线。
# 变换矩阵M是由原始图的固定点和目标图的点共同确定。给定的原始图参考下图所示。利用OpenCV + Python环境，参照下列步骤，完成图像矫正处理（35 分）

# （1）读取图像文件phototext.jpg
img = cv.imread('images/phototext.jpg', cv.IMREAD_COLOR)
H, W, CH = img.shape

# （2）图像旋转180度，使图像正立
M = cv.getRotationMatrix2D((W//2, H//2), 180, 1)
img_180 = cv.warpAffine(img, M, (W, H))

# （3）确定原始图4个顶点的坐标
pts1 = np.float32([(321, 497), (2129, 505), (217, 3145), (2089, 3201)])

# （4）确定目标图4个顶点的坐标（自定目标图尺度）
pts2 = np.float32([(0, 0), (W, 0), (0, H), (W, H)])

# （5）由上述坐标顶点，确定变换矩阵M
M = cv.getPerspectiveTransform(pts1, pts2)

# （6）由原始图和变换矩阵M获得目标图
img_dst = cv.warpPerspective(img_180, M, (W, H))  # ATTENTION warpPerspective vs. warpAffine

# （7）显示原始图和目标图
img_all = np.concatenate((img, img_dst), axis=1)
rate = 600 / H
img_all = cv.resize(img_all, None, fx=rate, fy=rate, interpolation=cv.INTER_CUBIC)
cv.imshow('src and dst', img_all)

cv.waitKey()
cv.destroyAllWindows()
